package com.sangmo.fts;

import com.sangmo.boot.framework.common.dict.DictionaryManager;
import com.sangmo.boot.framework.common.i18n.MessageMaker;
import com.sangmo.boot.framework.data.filter.SimpleQuery;
import com.sangmo.boot.framework.data.json.load.impl.JPALoader;
import com.sangmo.boot.framework.plugin.dataview.def.types.StringType;
import com.sangmo.boot.framework.plugin.dataview.def.types.TypeRegister;
import com.sangmo.boot.framework.plugin.dataview.spi.IntegrationPatch;
import com.sangmo.boot.framework.plugin.dataview.spi.api.DataViewIntegratedValidator;
import com.sangmo.boot.framework.plugin.dataview.spi.jpa.ValidationEntityRepoFactoryBean;
import com.sangmo.fts.basic.model.Company;
import com.sangmo.fts.common.IConstants;
import com.sangmo.fts.process.inventory.model.IfInbound;
import com.sangmo.fts.process.inventory.model.IfLadingBill;
import com.sangmo.fts.process.inventory.model.IfOutbound;
import com.sangmo.fts.process.inventory.model.IfStock;
import com.sangmo.fts.process.inventory.model.IfWaybill;
import com.sangmo.fts.process.inventory.model.IfLoan;
import com.sangmo.fts.process.storage.model.CsfInbound;
import com.sangmo.fts.process.storage.model.CsfLadingBill;
import com.sangmo.fts.process.storage.model.CsfLoan;
import com.sangmo.fts.process.storage.model.CsfOutbound;
import com.sangmo.fts.process.storage.model.CsfStock;
import com.sangmo.fts.process.storage.model.CsfWaybill;
import com.sangmo.fts.teacher.model.Examination;
import com.sangmo.fts.training.model.Team;
import com.sangmo.fts.training.model.Training;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import javax.annotation.PostConstruct;
import javax.validation.Validator;

@Configuration
@EnableJpaRepositories(basePackages = { "com.sangmo" }, repositoryFactoryBeanClass = ValidationEntityRepoFactoryBean.class)
@EntityScan(basePackages = { "com.sangmo" })
//@EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class DataViewConfig extends IntegrationPatch {

    @Bean
    public JPALoader jpaLoader() {
        return new JPALoader();
    }

    @Bean
    public SimpleQuery simpleQuery() {
        return new SimpleQuery();
    }

    @Override
    @Bean
    public Validator validator() {
        return new DataViewIntegratedValidator();
    }

    @Bean
    public DictionaryManager dictionaryManager(MessageMaker messageMaker) throws Exception {
        DictionaryManager dictionaryManager = new DictionaryManager();
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("dictionary/*.json");
        dictionaryManager.setMessageMaker(messageMaker);
        dictionaryManager.init(resources);
        return dictionaryManager;
    }
    @Autowired
    private ReloadableResourceBundleMessageSource messageSource;
    @Autowired
    private DictionaryManager dictionaryManager;

    @Value("${dataview.config.package.uri}")
    private String dataViewPackageUri;

    @PostConstruct
    private void init() throws Exception {
        //
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources(dataViewPackageUri+"*");
        for (Resource resource : resources) {
            messageSource.addBasenames(dataViewPackageUri + (resource.getFilename().substring(0, resource.getFilename().lastIndexOf("."))));
        }

       /* messageSource.addBasenames("classpath:i18n/examination");
        messageSource.addBasenames("classpath:i18n/messages/company");
        messageSource.addBasenames("classpath:i18n/messages/notice");
        messageSource.addBasenames("classpath:i18n/messages/score");
        messageSource.addBasenames("classpath:i18n/messages/ifContract");
        messageSource.addBasenames("classpath:i18n/messages/ifWaybill");
        messageSource.addBasenames("classpath:i18n/messages/ifStock");
        messageSource.addBasenames("classpath:i18n/messages/ifLoan");
        messageSource.addBasenames("classpath:i18n/messages/ifRepayment");

        messageSource.addBasenames("classpath:i18n/messages/csfAgreement");
        messageSource.addBasenames("classpath:i18n/messages/csfAssurance");*/
        /*Resource resource = new PathMatchingResourcePatternResolver().getResource("dictionary/examination.json");
        Map map = JsonUtils.createMapper().readValue(resource.getInputStream(), HashMap.class);
        dictionaryManager.put("Examination", map);*/

        this.registerDataTypes();
    }

    private void registerDataTypes() {
        TypeRegister register = TypeRegister.getInstance();

        register.add(new StringType(IConstants.COMPANY_DATA_TYPE.COMPANY_TYPE, Company.Type.class));
        register.add(new StringType(IConstants.COMPANY_DATA_TYPE.COMPANY_CREDIT_RATING, Company.CreditRating.class));

        register.add(new StringType(IConstants.EXAMINATION_DATA_TYPE.EXAMINATION_BUSINESS_TYPE, Examination.BusinessTypes.class));
        register.add(new StringType(IConstants.EXAMINATION_DATA_TYPE.EXAMINATION_MODE, Examination.Modes.class));
        register.add(new StringType(IConstants.EXAMINATION_DATA_TYPE.EXAMINATION_STATE, Examination.States.class));

        register.add(new StringType(IConstants.TRAINING_DATA_TYPE.TRAINING_BUSINESS_TYPE, Training.BusinessTypes.class));
        register.add(new StringType(IConstants.TRAINING_DATA_TYPE.TRAINING_STATE, Training.States.class));
        register.add(new StringType(IConstants.TRAINING_DATA_TYPE.TRAINING_MODE, Training.Modes.class));

        register.add(new StringType(IConstants.TEAM_DATA_TYPE.TEAM_BUSINESS_TYPE, Team.BusinessTypes.class));

        //IF
        register.add(new StringType(IConstants.IF_WAYBILL_DATA_TYPE.WAYBILL_STATE, IfWaybill.States.class));
//        register.add(new StringType(IConstants.IF_WAYBILL_DATA_TYPE.WAYBILL_SHIP_STATE, IfWaybill.ShipStates.class));
//        register.add(new StringType(IConstants.IF_WAYBILL_DATA_TYPE.WAYBILL_RECEIVE_STATE, IfWaybill.ReceiveStates.class));
        register.add(new StringType(IConstants.IF_STOCK_DATA_TYPE.STOCK_STATE, IfStock.States.class));
        register.add(new StringType(IConstants.IF_LOAN_DATA_TYPE.LOAN_STATE, IfLoan.States.class));
        register.add(new StringType(IConstants.IF_LOAN_DATA_TYPE.LOAN_DURATION, IfLoan.Duration.class));

        register.add(new StringType(IConstants.IF_LADING_BILL_DATA_TYPE.BILL_STATE, IfLadingBill.States.class));
        register.add(new StringType(IConstants.IF_LADING_BILL_DATA_TYPE.BANK_ACK_STATE, IfLadingBill.BankAckStates.class));
        register.add(new StringType(IConstants.IF_LADING_BILL_DATA_TYPE.STORAGE_ACK_STATE, IfLadingBill.StorageAckStates.class));

        register.add(new StringType(IConstants.IF_OUTBOUND_DATA_TYPE.OUTBOUND_STATE, IfOutbound.States.class));
        register.add(new StringType(IConstants.IF_INBOUND_DATA_TYPE.INBOUND_STATE, IfInbound.States.class));

        //CSF
        register.add(new StringType(IConstants.CSF_WAYBILL_DATA_TYPE.WAYBILL_STATE, CsfWaybill.States.class));
        register.add(new StringType(IConstants.CSF_LOAN_DATA_TYPE.LOAN_STATE, CsfLoan.States.class));
        register.add(new StringType(IConstants.CSF_LOAN_DATA_TYPE.LOAN_DURATION, CsfLoan.Duration.class));
        register.add(new StringType(IConstants.CSF_STOCK_DATA_TYPE.STOCK_STATE, CsfStock.States.class));

        register.add(new StringType(IConstants.CSF_LADING_BILL_DATA_TYPE.BILL_STATE, CsfLadingBill.States.class));
        register.add(new StringType(IConstants.CSF_LADING_BILL_DATA_TYPE.BANK_ACK_STATE, CsfLadingBill.BankAckStates.class));
        register.add(new StringType(IConstants.CSF_LADING_BILL_DATA_TYPE.STORAGE_ACK_STATE, CsfLadingBill.StorageAckStates.class));

        register.add(new StringType(IConstants.CSF_OUTBOUND_DATA_TYPE.OUTBOUND_STATE, CsfOutbound.States.class));
        register.add(new StringType(IConstants.CSF_INBOUND_DATA_TYPE.INBOUND_STATE, CsfInbound.States.class));
    }

}

